home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
quartz
/
q0714.dms
/
q0714.adf
/
Devices
/
NarratorDevice
/
Example6.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-29
|
13KB
|
462 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) V3.0 Amiga C Club (ACC) */
/* ------------------------------- ------------------ */
/* */
/* Book: ACM Devices Amiga C Club */
/* Chapter: Narrator Device Tulevagen 22 */
/* File: Example6.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 92-04-26 */
/* Version: 1.00 */
/* */
/* Copyright 1992, Anders Bjerin - Amiga C Club (ACC) */
/* */
/* Registered members may use this program freely in their */
/* own commercial/noncommercial programs/articles. */
/* */
/***********************************************************/
/* This example demonstrates how to use the mouth */
/* request block to draw a talking mouth. */
/* We are using Intuition: */
#include <intuition/intuition.h>
/* We are also using the narrator device: */
#include <devices/narrator.h>
/* Size of the phonetic string buffer. */
#define PHONETIC_BUFFER_SIZE 200
/* The size of the window: */
#define WIDTH 320
#define HEIGHT 200
/* Mouth position: */
#define MOUTH_X (WIDTH>>1)
#define MOUTH_Y (HEIGHT>>1)
/* The mouth's size: */
#define SCALE 5
/* The audio channels: */
/* Values: */
#define LEFT0B 0
#define RIGHT0B 1
#define RIGHT1B 2
#define LEFT1B 3
/* Bit fields: */
#define LEFT0F (1<<LEFT0B)
#define RIGHT0F (1<<RIGHT0B)
#define RIGHT1F (1<<RIGHT1B)
#define LEFT1F (1<<LEFT1B)
/* Pointer to the Intuition Library: */
struct IntuitionBase *IntuitionBase;
/* Pointer to the Graphics Library: */
struct GfxBase *GfxBase;
/* Pointer to the translator library: */
struct Library *TranslatorBase;
/* Declare a pointer to our reply port: */
struct MsgPort *replymp = NULL;
/* Declare a pointer to our narrator request block: */
struct narrator_rb *narrator_req = NULL;
/* Declare a pointer to our mouth request block: */
struct mouth_rb *mouth_req = NULL;
/* The text should be read in stereo: */
UBYTE allocation_array[]=
{
LEFT0F|RIGHT0F, /* First left and first right channel. */
LEFT0F|RIGHT1F, /* First left and second right channel. */
LEFT1F|RIGHT0F, /* Second left and first right channel. */
LEFT1F|RIGHT1F /* Second left and second right channel. */
};
/* Declare a pointer to a Window structure: */
struct Window *my_window;
/* Declare and initialize your NewWindow structure: */
struct NewWindow my_new_window=
{
50, /* LeftEdge x position of the window. */
50, /* TopEdge y positio of the window. */
WIDTH, /* Width The width of the window. */
HEIGHT, /* Height The height of the window. */
0, /* DetailPen Text should be drawn with colour reg. 0 */
1, /* BlockPen Blocks should be drawn with colour reg. 1 */
NULL, /* IDCMPFlags No IDCMP flags. */
SMART_REFRESH| /* Flags Intuition should refresh the window. */
WINDOWCLOSE| /* Close Gadget. */
WINDOWDRAG| /* Drag gadget. */
WINDOWDEPTH| /* Depth arrange Gadgets. */
ACTIVATE, /* The window should be Active when opened. */
NULL, /* FirstGadget No Custom Gadgets. */
NULL, /* CheckMark Use Intuition's default CheckMark (v). */
"The talking window!", /* Title Title of the window. */
NULL, /* Screen Connected to the Workbench Screen. */
NULL, /* BitMap No Custom BitMap. */
0, /* MinWidth We do not need to care about these */
0, /* MinHeight since we havent supplied the window with */
0, /* MaxWidth a Sizing Gadget. */
0, /* MaxHeight */
WBENCHSCREEN /* Type Connected to the Workbench Screen. */
};
/* Declare our functions: */
void main();
void clean_up( STRPTR text );
void draw_mouth
(
struct RastPort *rp,
UBYTE width,
UBYTE height,
UBYTE colour
);
void main()
{
/* Number of translated characters, or zero */
/* if all characters were translated: */
int char_translated;
/* The original string: */
char *original_string = "This is a talking picture! Only the Amiga makes it possible!";
/* The phonetic string: */
char phonetic_string[ PHONETIC_BUFFER_SIZE ];
/* Store error values here: */
BYTE error;
/* TRUE as long the Amiga is reading text: */
BOOL still_talking;
/* Pointer to the window's RastPort: */
struct RastPort *rast_port;
/* Previous mouth size: */
UBYTE old_mouth_height;
UBYTE old_mouth_width;
/* Since this program uses a window we have to */
/* open the Intuition library, and since we use */
/* the low level graphical functions Move(), */
/* Draw() etc, we have to open the Graphical */
/* library. */
/* Open the Intuition Library: */
IntuitionBase = (struct IntuitionBase *)
OpenLibrary( "intuition.library", 0 );
/* Have we successfully opened the library? */
if( !IntuitionBase )
clean_up( "Could not open the Intuition Library!" );
/* Open the Graphics library: */
GfxBase = (struct GfxBase *)
OpenLibrary( "graphics.library", 0 );
/* Have we successfully opened the library? */
if( !GfxBase )
clean_up( "Could not open the Graphics library!" );
/* Open the translator library: */
TranslatorBase = (struct Library *)
OpenLibrary( "translator.library", 0 );
/* Have we successfully opened the library? */
if( !TranslatorBase )
clean_up( "Could not open the translator library!" );
/* We will now try to open the window: */
my_window = (struct Window *)
OpenWindow( &my_new_window );
/* Have we successfully opened the window? */
if( !my_window )
clean_up( "Could not open the Window!" );
/* Get the address of the window's RastPort: */
rast_port = my_window->RPort;
printf( "A picture can say more than thousand words,\n" );
printf( "but this is ridiculous!\n" );
/* Translate our string into phonetics: (The Translate() */
/* functipon can sadly only translate English text, but */
/* with small modifications of the phonetic string it */
/* can be used with most languages.) */
char_translated =
Translate( original_string, strlen( original_string ),
phonetic_string, PHONETIC_BUFFER_SIZE );
/* If all characters could successfully be translated */
/* and stored in the phonetic string Translate() */
/* returns zero, else a negativa value is returned */
/* which tells us how many characters were actually */
/* translated: (Note that we put a minus sign infront */
/* of the variable to make it positive.) */
if( char_translated )
printf( "Translated only %d characters!\n", -char_translated );
/* Get a reply port: (No name, priority 0) */
replymp = (struct MsgPort *)
CreatePort( NULL, 0 );
if( !replymp )
clean_up( "Could not create the reply port!" );
/* Allocate and preinitialize a narrator request block: */
narrator_req = (struct narrator_rb *)
CreateExtIO( replymp, sizeof( struct narrator_rb ) );
if( !narrator_req )
clean_up( "Not enough memory for the narrator request!" );
/* Open the Narrator Device: */
error = OpenDevice( "narrator.device", 0, narrator_req, 0 );
if( error )
{
/* Clear the "io_Device" flag since */
/* we have not opened the device: */
narrator_req->message.io_Device = NULL;
/* Quit: */
clean_up( "Could not open the Narrator Device!" );
}
/* Allocate and preinitialize the mouth request block: */
mouth_req = (struct mouth_rb *)
CreateExtIO( replymp, sizeof( struct mouth_rb ) );
if( !mouth_req )
clean_up( "Not enough memory for the mouth request!" );
/* Initialize the mouth request: */
/* Set the mouth width and heigh to zero: */
mouth_req->width = 0;
mouth_req->height = 0;
/* Copy the mouth values: */
old_mouth_height = mouth_req->width;
old_mouth_width = mouth_req->height;
/* Give the mouth request a pointer to the narrator device: */
mouth_req->voice.message.io_Device = narrator_req->message.io_Device;
/* Give the mouth request the current unit number: */
mouth_req->voice.message.io_Unit = narrator_req->message.io_Unit;
/* No error number (so far): */
mouth_req->voice.message.io_Error = 0;
/* The mouth request shuld look at (read) the request */
/* which is currently talking: */
mouth_req->voice.message.io_Command = CMD_READ;
/* Set our requirements: */
/* Set the length of the phonetic string: */
narrator_req->message.io_Length = strlen( phonetic_string );
/* Give it a pointer to the phonetic string: */
narrator_req->message.io_Data = (APTR) phonetic_string;
/* Send (write) the text to the device: */
narrator_req->message.io_Command = CMD_WRITE;
/* Desired channel combinations: */
narrator_req->ch_masks = allocation_array;
/* Size of the allocation array: */
narrator_req->nm_masks = sizeof( allocation_array );
/* Generate mouth values: */
narrator_req->mouths = TRUE;
/* Normal (one colour) draw mode: */
SetDrMd( rast_port, JAM1 );
/* Start to read: */
SendIO( narrator_req );
/* The Amiga is still reading the text: */
still_talking = TRUE;
/* As long as the Amiga is reading the text */
/* we stay in the while loop: */
while( still_talking )
{
/* Send the mouth request to the narrator device. The request */
/* will be returned when the mouth width and/or heigh have */
/* changed, or the device has stopped reading the text: */
DoIO( mouth_req );
/* Has the device stopped reading thel text: */
if( mouth_req->voice.message.io_Error == ND_NoWrite )
still_talking = FALSE;
else
{
/* No, the device is still reading. The mouth must have */
/* changed, so we better redraw it: */
/* Remove the old mouth: */
draw_mouth
(
rast_port,
old_mouth_width,
old_mouth_height,
0
);
/* Draw the new mouth: */
draw_mouth
(
rast_port,
mouth_req->width,
mouth_req->height,
1
);
/* Save the mouth values: */
old_mouth_width = mouth_req->width;
old_mouth_height = mouth_req->height;
}
}
/* We know that the Amiga has stopped speaking, */
/* and hence we do not have to wait for the */
/* narrator to finish reading. We should however */
/* check if we have successfully read the text: */
if( narrator_req->message.io_Error )
{
printf( "Error code: %d\n", narrator_req->message.io_Error );
clean_up( "Error while reading!" );
}
/* Clean up and quit: */
clean_up( "The End!" );
}
/* Close and return everything that has been */
/* opened and allocated before we quit: */
void clean_up( STRPTR text )
{
/* If we have a request block and the "io_Device" field */
/* is not zero, we know that the device has successfully */
/* been opened and must now be closed: */
if( narrator_req && narrator_req->message.io_Device )
CloseDevice( narrator_req );
/* Empty the reply port: */
while( GetMsg( replymp ) )
printf( "Collected a message at the reply port.\n" );
/* Remove the replyport: */
if( replymp )
DeletePort( replymp);
/* Dealocate the narrator request block: */
if( narrator_req )
DeleteExtIO( narrator_req, sizeof( struct narrator_rb ) );
/* Close the window: */
if( my_window )
CloseWindow( my_window );
/* Close the translator library: */
if( TranslatorBase )
CloseLibrary( TranslatorBase );
/* Close the Graphics library: */
if( GfxBase )
CloseLibrary( GfxBase );
/* Close the Intuition Library: */
if( IntuitionBase )
CloseLibrary( IntuitionBase );
/* Print the last message: */
printf( "%s\n", text );
/* Quit: */
exit( 0 );
}
/* This simple function will draw the mouth: */
void draw_mouth
(
struct RastPort *rp,
UBYTE width,
UBYTE height,
UBYTE colour
)
{
/* Set colour: */
SetAPen( rp, colour );
/* Start position: */
Move( rp, MOUTH_X - width * SCALE, MOUTH_Y );
/* Draw the mouth: */
Draw( rp, MOUTH_X, MOUTH_Y - height * SCALE );
Draw( rp, MOUTH_X + width * SCALE, MOUTH_Y );
Draw( rp, MOUTH_X, MOUTH_Y + height * SCALE );
Draw( rp, MOUTH_X - width * SCALE, MOUTH_Y );
}